<?php

error_reporting(0);
define('IN_MOBILE', true);
require dirname(__FILE__).'/../../../../framework/bootstrap.inc.php';
require IA_ROOT.'/addons/mx_shop/defines.php';
require IA_ROOT.'/addons/mx_shop/core/inc/functions.php';
require IA_ROOT.'/addons/mx_shop/core/inc/plugin_model.php';
require IA_ROOT.'/addons/mx_shop/core/inc/com_model.php';

class aliApy
{
    public $post;
    public $subject;
    public $body;
    public $strs;
    public $type;
    public $total_fee;
    public $setting;
    public $sec;
    public $isapp = false;

    public function __construct()
    {
        global $_W;
        $this->post = $_POST;
        if (!empty($this->post['subject'])){
            $this->subject = iconv('gbk','utf-8',$this->post['subject']);
        }
        if (!empty($this->post['body'])){
            $this->body = iconv('gbk','utf-8',$this->post['body']);
        }
        if (empty($this->post)){
            exit('fail');
        }
        if (!empty($this->post['notify_type'])){
            if ($this->post['notify_type'] == 'batch_trans_notify'){
                $this->batch_trans_notify();
            }elseif ($this->post['notify_type'] == 'batch_refund_notify'){
                $this->batch_refund_notify();
            }
        }
        if($this->post['trade_status']!='TRADE_SUCCESS'){
            exit('fail');
        }
        $this->strs = explode(':', $this->body);
        $this->type = intval($this->strs[1]); //类型 0 购物 1 充值 2收银台
        $this->total_fee= round($this->post['total_fee'],2);
        $GLOBALS['_W']['uniacid'] = intval($this->strs[0]);
        $_W['uniacid'] = intval($this->strs[0]);
        $this->init();
    }

    public function init()
    {
        if ($this->type == '0'){
            $this->order();
        }elseif ($this->type == '1'){
            $this->recharge();
        }elseif ($this->type == '2'){
            $this->cashier();
        }elseif ($this->type == '6'){
            $this->threen();
        }elseif ($this->type == '20'){
            $this->creditShop();

        }
        exit('success');
    }

    /**
     * 订单支付
     */
    public function order()
    {
        if (!$this->publicMethod()){
            exit(__FUNCTION__);
        }
        $tid = $this->post['out_trade_no'];
        if(strexists($tid,'GJ')){
            $tids = explode("GJ",$tid);
            $tid = $tids[0];
        }
        $sql = 'SELECT * FROM ' . tablename('core_paylog') . ' WHERE `tid`=:tid and `module`=:module limit 1';
        $params = array();
        $params[':tid'] = $tid;
        $params[':module'] = 'mx_shop';
        $log = pdo_fetch($sql, $params);

        if($this->post['total_fee']!=$log['fee']){
            exit('fail');
        }

        if (!empty($log) && $log['status'] == '0') {
            $site = WeUtility::createModuleSite($log['module']);
            if (!is_error($site)) {
                $method = 'payResult';
                if (method_exists($site, $method)) {
                    $ret = array();
                    $ret['acid'] = $log['acid'];
                    $ret['uniacid'] = $log['uniacid'];
                    $ret['result'] = 'success';
                    $ret['type'] = 'alipay';
                    $ret['from'] = 'return';
                    $ret['tid'] = $log['tid'];
                    $ret['user'] = $log['openid'];
                    $ret['fee'] = $log['fee'];
                    $ret['is_usecard'] = $log['is_usecard'];
                    $ret['card_type'] = $log['card_type'];
                    $ret['card_fee'] = $log['card_fee'];
                    $ret['card_id'] = $log['card_id'];

                    pdo_update('mx_shop_order', array('paytype' => 22),array('uniacid'=>$log['uniacid'],'ordersn' => $log['tid']));

                    $result = $site->$method($ret);
                    if ($result) {

                        $log['tag'] = iunserializer($log['tag']);
                        $log['tag']['transid'] = $this->post['trade_no'];

                        $record = array();
                        $record['status'] = '1';
                        $record['type'] = 'alipay';
                        $record['tag'] = iserializer($log['tag']);
                        pdo_update('core_paylog', $record, array('plid' => $log['plid']));
                        pdo_update('mx_shop_order', array('paytype' => 22, 'apppay'=>$this->isapp?1:0,'transid'=>$this->post['trade_no']), array('ordersn' => $log['tid'],'uniacid'=>$log['uniacid']));
                        exit('success');
                    }
                }
            }
        }
    }
    /**
     * 3N营销支付
     */
    public function threen()
    {
        global $_W;
        if (!$this->publicMethod()){
            exit(__FUNCTION__);
        }
        //充值
        $logno = trim($this->post['out_trade_no']);

        if (empty($logno)) {
            exit;
        }
        $log = pdo_fetch('SELECT * FROM ' . tablename('mx_shop_threen_log') . ' WHERE `uniacid`=:uniacid and id=:id limit 1', array(':uniacid' => $_W['uniacid'], ':id' => $logno));

        if($this->post['total_fee']!=$log['moneychange']){
            exit('fail');
        }
        if(p('threen')){
            p('threen')->payResult($log['logno'],'alipay', $this->isapp?true:false);
        }
    }
    /**
     * 会员充值
     */
    public function recharge()
    {
        global $_W;
        if (!$this->publicMethod()){
            exit(__FUNCTION__);
        }
        //充值
        $logno = trim($this->post['out_trade_no']);

        if (empty($logno)) {
            exit;
        }
        $log = pdo_fetch('SELECT * FROM ' . tablename('mx_shop_member_log') . ' WHERE `uniacid`=:uniacid and `logno`=:logno limit 1', array(':uniacid' => $_W['uniacid'], ':logno' => $logno));

        if($this->post['total_fee']!=$log['money']){
            exit('fail');
        }

        if (!empty($log) && empty($log['status'])) {
            //充值状态
            pdo_update('mx_shop_member_log', array('status' => 1, 'rechargetype' => 'alipay', 'apppay'=>$this->isapp?1:0,'transid'=>$this->post['trade_no']), array('id' => $log['id']));
            //增加会员余额
            $shopset = m('common')->getSysset('shop');
            m('member')->setCredit($log['openid'], 'credit2', $log['money'], array(0, $shopset['name'].'会员充值:credit2:' . $log['money']));
            //充值积分
            m('member')->setRechargeCredit($log['openid'], $log['money']);

            //充值活动
            com_run('sale::setRechargeActivity', $log);

            //优惠券
            com_run('coupon::useRechargeCoupon', $log);

            //模板消息
            m('notice')->sendMemberLogMessage($log['id']);
        }
    }

    /**
     * 收银台支付
     */
    public function cashier()
    {
        global $_W;
        $ordersn = trim($this->post['out_trade_no']);
        if (empty($ordersn)) {
            exit;
        }
        if(p('cashier')){
//            p('cashier')->payResult($ordersn);
        }
    }

    /**
     * 积分商城兑换
     */
    public function creditShop()
    {
        global $_W;
        if (!$this->publicMethod()){
            exit(__FUNCTION__);
        }
        //积分兑换
        $logno = trim($this->post['out_trade_no']);
        if (empty($logno)) {
            exit;
        }
        $logno = str_replace('_borrow','',$logno);
        /*$log = pdo_fetch('SELECT * FROM ' . tablename('mx_shop_creditshop_log') . ' WHERE `logno`=:logno and `uniacid`=:uniacid  limit 1', array(':uniacid' => $_W['uniacid'], ':logno' => $logno));
        if (!empty($log) && empty($log['status'])) {
            $goods = pdo_fetch("SELECT * FROM" .tablename("mx_shop_creditshop_goods") . "WHERE id=:id and uniacid=:uniacid limit 1 ",array(":id"=>$log['goodsid'], ":uniacid"=>$_W['uniacid']));
            if(!empty($goods) && $this->total_fee==$goods['money']){
                pdo_update('mx_shop_creditshop_log', array('paystatus' => 1, 'paytype' => 1), array('id' => $log['id']));
            }
        }*/

        if(p('creditshop')){
            p('creditshop')->payResult($logno,'alipay',$this->total_fee, $this->isapp?true:false);
        }
    }

    public function batch_trans_notify()
    {
        $post = explode('MONEY',substr($this->post['batch_no'],11));
        $id = $post[0];
        $money = $post[1];

        //CP 佣金打款 RW 余额提现
        if (strexists($this->post['batch_no'],'CP')){
            $this->batch_trans_notify_cp($id,$money);
        }elseif (strexists($this->post['batch_no'],'RW')){
            $this->batch_trans_notify_rw($id,$money);
        }
        exit('success');
    }

    /**
     * 支付宝佣金打款回调
     * @param $id
     * @param $money
     */
    public function batch_trans_notify_cp($id,$money)
    {
        global $_W;

        $apply = pdo_fetch('select * from ' . tablename('mx_shop_commission_apply') . ' where id=:id limit 1'
            , array(':id' => $id));

        if (empty($apply) || $apply['status']=='3') {
            exit;
        }
        if ($money!=$apply['realmoney']*100){
            exit;
        }
        $GLOBALS['_W']['uniacid']= $apply['uniacid'];
        $_W['uniacid']= $apply['uniacid'];


        //下级代理
        $agentid = $apply['mid'];
        $member = p('commission')->getInfo($agentid, array('total', 'ok', 'apply', 'lock', 'check'));
        $hasagent = $member['agentcount'] > 0;
        $agentLevel = p('commission')->getLevel($apply['mid']);
        $set = p('commission')->getSet();
        if (empty($agentLevel['id'])) {
            $agentLevel = array(
                'levelname' => empty($set['levelname']) ? '普通等级' : $this->set['levelname'],
                'commission1' => $set['commission1'],
                'commission2' => $set['commission2'],
                'commission3' => $set['commission3'],
            );
        }

        $orderids = iunserializer($apply['orderids']);
        if (!is_array($orderids) || count($orderids) <= 0) {
            exit;
        }
        $ids = array();
        foreach ($orderids as $o) {
            $ids[] = $o['orderid'];
        }

        $list = pdo_fetchall("select id,agentid, ordersn,price,goodsprice, dispatchprice,createtime, paytype from " . tablename('mx_shop_order') . " where  id in ( " . implode(",", $ids) . " );");
        $totalcommission = 0;
        $totalpay = 0;
        $totalmoney = 0;
        foreach ($list as &$row) {
            //判断是几级订单
            foreach ($orderids as $o) {
                if ($o['orderid'] == $row['id']) {
                    $row['level'] = $o['level'];
                    break;
                }
            }
            $goods = pdo_fetchall("SELECT og.id,g.thumb,og.price,og.realprice, og.total,g.title,o.paytype,og.optionname,og.commission1,og.commission2,og.commission3,og.commissions,og.status1,og.status2,og.status3,og.content1,og.content2,og.content3 from " . tablename('mx_shop_order_goods') . " og"
                . " left join " . tablename('mx_shop_goods') . " g on g.id=og.goodsid  "
                . " left join " . tablename('mx_shop_order') . " o on o.id=og.orderid  "
                . " where og.uniacid = :uniacid and og.orderid=:orderid and og.nocommission=0 order by og.createtime  desc ", array(':uniacid' => $_W['uniacid'], ':orderid' => $row['id']));

            foreach ($goods as &$g) {
                $commissions = iunserializer($g['commissions']);
                if ($set['level'] >= 1) {
                    $commission = iunserializer($g['commission1']);

                    if (empty($commissions)) {
                        $g['commission1'] = isset($commission['level' . $agentLevel['id']]) ? $commission['level' . $agentLevel['id']] : $commission['default'];
                    } else {
                        $g['commission1'] = isset($commissions['level1']) ? floatval($commissions['level1']) : 0;
                    }
                    if ($row['level'] == 1) {
                        $totalcommission+=$g['commission1'];
                        if ($g['status1'] >= 2) {
                            $totalpay+=$g['commission1'];
                        }
                    }
                }
                if ($set['level'] >= 2) {
                    $commission = iunserializer($g['commission2']);
                    if (empty($commissions)) {
                        $g['commission2'] = isset($commission['level' . $agentLevel['id']]) ? $commission['level' . $agentLevel['id']] : $commission['default'];
                    } else {
                        $g['commission2'] = isset($commissions['level2']) ? floatval($commissions['level2']) : 0;
                    }


                    if ($row['level'] == 2) {
                        $totalcommission+=$g['commission2'];
                        if ($g['status2'] >= 2) {
                            $totalpay+=$g['commission2'];
                        }
                    }
                }
                if ($set['level'] >= 3) {

                    $commission = iunserializer($g['commission3']);
                    if (empty($commissions)) {
                        $g['commission3'] = isset($commission['level' . $agentLevel['id']]) ? $commission['level' . $agentLevel['id']] : $commission['default'];
                    } else {
                        $g['commission3'] = isset($commissions['level3']) ? floatval($commissions['level3']) : 0;
                    }

                    if ($row['level'] == 3) {
                        $totalcommission+=$g['commission3'];
                        if ($g['status3'] >= 2) {
                            $totalpay+=$g['commission3'];
                        }
                    }
                }
                $g['level'] = $row['level'];
            }
            unset($g);
            $row['goods'] = $goods;
            $totalmoney+=$row['price'];
        }

        unset($row);

        $set_array = array();
        $set_array['charge'] = $apply['charge'];
        $set_array['begin'] = $apply['beginmoney'];
        $set_array['end'] = $apply['endmoney'];

        $realmoney = $totalpay;
        $deductionmoney = 0;
        if (!empty($set_array['charge'])) {
            $money_array = m('member')->getCalculateMoney($totalpay, $set_array);

            if($money_array['flag']) {
                $realmoney = $money_array['realmoney'];
                $deductionmoney = $money_array['deductionmoney'];
            }
        }
        $apply_type = array( 0 => '余额', 1 => '微信钱包', 2 => '支付宝', 3 => '银行卡');

        $time = time();

        foreach ($list as $row) {
            $update = array();
            foreach ($row['goods'] as $g) {
                $update = array();
                if ($row['level'] == 1 && $g['status1'] == 2) {
                    $update = array('paytime1' => $time, 'status1' => 3);
                } else if ($row['level'] == 2 && $g['status2'] == 2) {
                    $update = array('paytime2' => $time, 'status2' => 3);
                } else if ($row['level'] == 3 && $g['status3'] == 2) {
                    $update = array('paytime3' => $time, 'status3' => 3);
                }
                if (!empty($update)) {
                    pdo_update('mx_shop_order_goods', $update, array('id' => $g['id']));
                }
            }
        }
        pdo_update('mx_shop_commission_apply', array('status' => 3, 'paytime' => $time, 'commission_pay' => $totalpay, 'realmoney' => $realmoney, 'deductionmoney' => $deductionmoney), array('id' => $id, 'uniacid' => $_W['uniacid']));

        //佣金打款记录
        $log = array(
            'uniacid' => $_W['uniacid'],
            'applyid' => $apply['id'],
            'mid' => $member['id'],
            'commission' => $totalcommission,
            'commission_pay' => $totalpay,
            'realmoney' => $realmoney,
            'deductionmoney' => $deductionmoney,
            'charge' => $set_array['charge'],
            'createtime' => $time,
            'type' => $apply['type']
        );
        pdo_insert('mx_shop_commission_log', $log);

        $mcommission = $totalpay;
        if (!empty($deductionmoney)) {
            $mcommission .= ',实际到账金额:' . $realmoney . ',提现手续费金额:' . $deductionmoney;
        }

        //发送打款处理消息
        p('commission')->sendMessage($member['openid'], array('commission' => $mcommission, 'type' => $apply_type[$apply['type']]), TM_COMMISSION_PAY);
        //升级
        p('commission')->upgradeLevelByCommissionOK($member['openid']);

        //股东升级
        if(p('globous')){
            p('globous')->upgradeLevelByCommissionOK($member['openid']);
        }

        plog('commission.apply.pay', "佣金打款 ID: {$id} 申请编号: {$apply['applyno']} 打款方式: {$apply_type[$apply['type']]} 总佣金: {$totalcommission} 审核通过佣金: {$totalpay} 实际到账金额: {$realmoney} 提现手续费金额: {$deductionmoney} 提现手续费税率: {$set_array['charge']}%");
    }

    /**
     * 余额提现回调
     * @param $id
     * @param $money
     */
    public function batch_trans_notify_rw($id,$money)
    {
        $log = pdo_fetch('select * from ' . tablename('mx_shop_member_log') . ' where id=:id limit 1', array(
            ':id' => $id
        ));
        if (empty($log) || $log['status']=='1') {
            exit;
        }
        if ($money!=$log['realmoney']*100){
            exit;
        }
        $GLOBALS['_W']['uniacid'] = $log['uniacid'];
        $_W['uniacid'] = $log['uniacid'];

        pdo_update('mx_shop_member_log', array('status' => 1), array('id' => $id, 'uniacid' => $_W['uniacid']));

        //模板消息
        m('notice')->sendMemberLogMessage($log['id']);
        $member = m('member')->getMember($log['openid']);
        plog('finance.log.wechat', "余额提现 ID: {$log['id']} 方式: 微信 提现金额: {$log['money']} ,到账金额: {$money} ,手续费金额 : {$log['deductionmoney']}<br/>会员信息:  ID: {$member['id']} / {$member['openid']}/{$member['nickname']}/{$member['realname']}/{$member['mobile']}");
    }

    public function batch_refund_notify()
    {
        $post = explode('MONEY',substr($this->post['batch_no'],10));
        $id = $post[0];
        $money = $post[1];

        //RF 支付宝订单退款
        if (strexists($this->post['batch_no'],'RF')){
            $this->batch_refund_notify_rf($id,$money);

        }elseif (strexists($this->post['batch_no'],'RC')){//充值退款
            $this->batch_refund_notify_rc($id,$money);
        }
        exit('success');
    }

    /**
     * 支付宝订单退款
     * @param $id
     * @param $money
     */
    public function batch_refund_notify_rf($id,$money)
    {
        $item = pdo_fetch("SELECT * FROM " . tablename('mx_shop_order') . " WHERE id = :id limit 1", array(':id' => $id));
        if (empty($item)) {
            exit;
        }
        $GLOBALS['_W']['uniacid'] = $item['uniacid'];
        $_W['uniacid'] = $item['uniacid'];
        $time = time();

        $goods = pdo_fetchall("SELECT g.id,g.credit, o.total,o.realprice FROM " . tablename('mx_shop_order_goods') .
            " o left join " . tablename('mx_shop_goods') . " g on o.goodsid=g.id " . " WHERE o.orderid=:orderid and o.uniacid=:uniacid", array(':orderid' => $item['id'], ':uniacid' => $item['uniacid']));

        //计算订单中商品累计赠送的积分
        $credits = m('order')->getGoodsCredit($goods);

        //扣除会员购物赠送积分
        if($credits>0){
            m('member')->setCredit($item['openid'], 'credit1', -$credits, array(0,"退款扣除购物赠送积分: {$credits} 订单号: " . $item['ordersn']));
        }

        //返还抵扣积分
        if ($item['deductcredit'] > 0) {
            m('member')->setCredit($item['openid'], 'credit1', $item['deductcredit'], array('0', "购物返还抵扣积分 积分: {$item['deductcredit']} 抵扣金额: {$item['deductprice']} 订单号: {$item['ordersn']}"));
        }
        if (!empty($refundtype)) {
            //在线支付，返还余额抵扣

            if ($money < 0) {
                $item['deductcredit2'] = $money;
            }
            m('order')->setDeductCredit2($item);
        }

        $change_refund['reply'] = '';
        $change_refund['status'] = 1;
        $change_refund['refundtype'] = $refundtype;
        $change_refund['price'] = round($money/100,2);
        $change_refund['refundtime'] = $time;

        if (empty($refund['operatetime'])) {
            $change_refund['operatetime'] = $time;
        }

        //同意
        pdo_update('mx_shop_order_refund', $change_refund, array('id' => $item['refundid']));

        //处理赠送余额情况
        m('order')->setGiveBalance($item['id'], 2);

        m('order')->setStocksAndCredits($item['id'], 2);


        if ($refund['orderprice'] == $refund['applyprice']) {
            //退还优惠券
            if (com('coupon') && !empty($item['couponid'])) {
                com('coupon')->returnConsumeCoupon($item['id']); //申请退款成功
            }
        }

        //更新订单退款状态
        pdo_update('mx_shop_order', array('refundstate' => 0, 'status' => -1, 'refundtime' => $time), array('id' => $item['id'], 'uniacid' => $item['uniacid']));

        //更新实际销量
        foreach ($goods as $g) {
            //实际销量
            $salesreal = pdo_fetchcolumn('select ifnull(sum(total),0) from ' . tablename('mx_shop_order_goods') . ' og '
                . ' left join ' . tablename('mx_shop_order') . ' o on o.id = og.orderid '
                . ' where og.goodsid=:goodsid and o.status>=1 and o.uniacid=:uniacid limit 1', array(':goodsid' => $g['id'], ':uniacid' => $item['uniacid']));
            pdo_update('mx_shop_goods', array('salesreal' => $salesreal), array('id' => $g['id']));
        }


        $log = "订单退款 ID: {$item['id']} 订单号: {$item['ordersn']}";

        if ($item['parentid'] > 0) {
            $log .= " 父订单号:{$item['ordersn']}";
        }

        plog('order.op.refund', $log);

        //模板消息
        m('notice')->sendOrderMessage($item['id'], true);
    }

    public function batch_refund_notify_rc($id,$money)
    {
        $log = pdo_fetch('select * from ' . tablename('mx_shop_member_log') . ' where id=:id limit 1', array(
            ':id' => $id
        ));
        if (empty($log)) {
            exit;
        }
        $GLOBALS['_W']['uniacid'] = $log['uniacid'];
        $_W['uniacid'] = $log['uniacid'];

        pdo_update('mx_shop_member_log', array('status' => 3), array('id' => $id, 'uniacid' => $_W['uniacid']));
        //减少余额 充值+赠送的
        $refundmoney = $log['money'] + $log['gives'];
        m('member')->setCredit($log['openid'], 'credit2', -$refundmoney, array(0,'充值退款'));

        //模板消息
        m('notice')->sendMemberLogMessage($log['id']);
        $member = m('member')->getMember($log['openid']);
        plog('finance.log.refund', "充值退款 ID: {$log['id']} 金额: {$log['money']} <br/>会员信息:  ID: {$member['id']} / {$member['openid']}/{$member['nickname']}/{$member['realname']}/{$member['mobile']}");
    }

    /**
     * 使用商城自带支付 公用方法
     * @return bool
     */
    public function publicMethod()
    {
        global $_W;
        $this->setting = uni_setting($_W['uniacid'], array('payment'));
        if (isset($this->strs[2]) && $this->strs[2]=='APP'){
            $wapset = m('common')->getSysset('wap');
            $this->setting['payment']['alipay'] = array(
                'switch'=>1,
                'public_key'=>$wapset['alipublic']
            );
        }
        if (!empty($this->setting['payment']['alipay'])){
            $sec_yuan = m('common')->getSec();
            $this->sec =iunserializer($sec_yuan['sec']);

            if ($this->post['sign_type']=="RSA"){
                if (isset($this->strs[2]) && $this->strs[2]=='APP'){
                    $public_key = $this->sec['app_alipay']['public_key'];
                    if(empty($public_key)){
                        exit;
                    }
                    $this->isapp = true;
                    return m('finance')->RSAVerify($this->post, $public_key, true);
                }
            }else{
                $prepares = array();
                foreach ($this->post as $key => $value) {
                    if ($key != 'sign' && $key != 'sign_type') {
                        $prepares[] = "{$key}={$value}";
                    }
                }
                sort($prepares);
                $string = implode($prepares, '&');
                $string .= $this->setting['payment']['alipay']['secret'];
                $sign = md5($string);
                if ($sign == $this->post['sign']){
                    return true;
                }
            }
        }
        return false;
    }
}
new aliApy();
